package net.guerlab.smart.wx.service.controller.mp;

import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpTemplateMsgService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import net.guerlab.smart.wx.core.message.SendMsgResponse;
import net.guerlab.smart.wx.core.message.WxMpTemplateMessageData;
import net.guerlab.smart.wx.core.message.WxMpTemplateMessageSendRequest;
import net.guerlab.smart.wx.service.controller.AbstractMsgController;
import net.guerlab.smart.wx.service.service.WxMpManagerService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 微信-公众号-模版消息
 *
 * @author guer
 */
public abstract class AbstractWxMpTemplateMsgController extends AbstractMsgController<WxMpTemplateMessageSendRequest> {

    protected WxMpManagerService wxMpManagerService;

    @Override
    protected Map<String, SendMsgResponse> sendMsg0(String appId, Collection<String> openIds,
            WxMpTemplateMessageSendRequest request) {
        WxMpTemplateMessageData msg = request.getMsg();

        WxMpTemplateMsgService msgService = wxMpManagerService.getService(appId).getTemplateMsgService();

        Map<String, SendMsgResponse> result = new ConcurrentHashMap<>(openIds.size());

        List<WxMpTemplateData> dataList = msg.getData().stream().map(this::toMsgData).filter(Objects::nonNull)
                .collect(Collectors.toList());

        openIds.forEach(openId -> {
            WxMpTemplateMessage sendMsg = new WxMpTemplateMessage();
            sendMsg.setToUser(openId);
            sendMsg.setTemplateId(msg.getTemplateId());
            sendMsg.setUrl(msg.getUrl());
            sendMsg.setData(dataList);

            SendMsgResponse response = new SendMsgResponse();
            result.put(openId, response);
            try {
                msgService.sendTemplateMsg(sendMsg);
                response.setStatus(true);
            } catch (WxErrorException e) {
                WxError error = e.getError();
                response.setErrorCode(error.getErrorCode());
                response.setErrorMsg(error.getErrorMsg());
            } catch (Exception e) {
                response.setErrorMsg(e.getLocalizedMessage());
            }
        });

        return result;
    }

    private WxMpTemplateData toMsgData(WxMpTemplateMessageData.TemplateData templateData) {
        if (templateData == null) {
            return null;
        }
        String name = StringUtils.trimToNull(templateData.getName());
        if (name == null) {
            return null;
        }

        WxMpTemplateData data = new WxMpTemplateData();
        data.setName(name);
        data.setValue(templateData.getValue());
        data.setColor(templateData.getColor());
        return data;
    }

    @Autowired
    public void setWxMpManagerService(WxMpManagerService wxMpManagerService) {
        this.wxMpManagerService = wxMpManagerService;
    }
}
